一个简单的例子
以下是来自 入门 仓库的简单硬件描述。
case class MyTopLevel() extends Component {
  val io = new Bundle {
    val cond0 = in port Bool()
    val cond1 = in port Bool()
    val flag  = out port Bool()
    val state = out port UInt(8 bits)
  }
  val counter = Reg(UInt(8 bits)) init 0
  when(io.cond0) {
    counter := counter + 1
  }
  io.state := counter
  io.flag  := (counter === 0) | io.cond1
}
它在本节中被分成多个块进行解释。
Component
首先,这里有一个 SpinalHDL Component 的结构。
组件是一段逻辑,可以根据需要多次实例化(粘贴),外部仅可通过输入和输出信号(io)对其访问。
case class MyTopLevel() extends Component {
  val io = new Bundle {
    // port definitions go here
  }
  // component logic goes here
}
MyTopLevel 是组件的名称。
在 SpinalHDL 中,组件使用 UpperCamelCase (驼峰命名法)。
备注
请参阅 组件 了解更多信息。
端口
然后,定义端口。
val cond0 = in port Bool()
val cond1 = in port Bool()
val flag = out port Bool()
val state = out port UInt(8 bits)
方向:
- cond0和- cond1是输入端口
- flag和- state是输出端口
类型:
- cond0,- cond1and- flagare 1 bit each (as 3 individual signals)
- stateis an 8-bit unsigned integer (a bus of 8 signals representing an unsigned integer)
备注
此语法仅自 SpinalHDL 1.8 起可用,请参阅 输入/输出定义 了解旧语法和更多信息。
内部逻辑
最后,还有组件的逻辑:
val counter = Reg(UInt(8 bits)) init(0)
when(io.cond0) {
  counter := counter + 1
}
io.state := counter
io.flag := (counter === 0) | io.cond1
counter 是一个包含 8 位无符号整数的寄存器,初始值为 0。更改寄存器状态的赋值仅可在下一个时钟采样后回读。
然后描述一个条件规则:当输入 cond0 (位于“io”线束中)被置1时,counter 加一,否则 counter 保持其值在最后一条规则中设置的值。但是,您可能会说,如果没有给出前置规则呢?对一个简单的**信号**来说,它将成为一个锁存器,并触发一个错误。但这里的 counter 是一个寄存器,所以它有一个默认值,没有其他规则,它就保持初始值。
这里创建了一个多路复用器: counter 寄存器的输入可以是其输出或其输出加一,这取决于 io.cond0 的值。
然后描述无条件规则(赋值):
- 输出端口 - state连接到寄存器- counter的输出。
- 输出端口 - flag是输入信号- cond1与另一信号之间的- or门的输出,该信号在- counter信号等于0时为真,否则为假。
备注
有关更多信息,请参阅 语义 。